import { isWebContents } from "@utils/electronValidate";
import { isNumber } from "@utils/judge";
import { ipcMain } from "electron";
import type {  WebContents } from "electron";
import type { Ipc_ChannelEnum } from "@enum/channel.enum";
import { getAllWindows, getWinById } from "./handle";

export class Ipc {
  static on<T extends FreeArray>(
    key: Ipc_ChannelEnum,
    fn: IpcMainListener<T>
  ): void {
    ipcMain.on(key, fn);
  }

  static once<T extends FreeArray>(
    key: Ipc_ChannelEnum,
    fn: IpcMainListener<T>
  ): void {
    ipcMain.once(key, fn);
  }

  static handle<T extends FreeArray>(
    key: Ipc_ChannelEnum,
    fn: IpcMainInvokeListener<T>
  ): void {
    ipcMain.handle(key, fn);
  }

  static handleOnce<T extends FreeArray>(
    key: Ipc_ChannelEnum,
    fn: IpcMainInvokeListener<T>
  ): void {
    ipcMain.handleOnce(key, fn);
  }

  static send<T>(sendCfg: {
    key: Ipc_ChannelEnum;
    params: T;
    identify?: number | WebContents;
  }): void {
    let { key, params, identify } = sendCfg;

    if (identify) {
      if (isWebContents(identify))
        this.sendByWebContents(key, params, identify);
      else if (isNumber(identify)) this.sendById(key, params, identify);
      else throw new Error("identify参数类型必须为number或WebContents");
    } else {
      getAllWindows().forEach((win) => {
        win?.webContents?.send(key, params);
      });
    }
  }

  static sendByWebContents<T>(
    key: Ipc_ChannelEnum,
    params: T,
    conetents: WebContents
  ): void {
    conetents?.send(key, params);
  }

  static sendById<T>(key: Ipc_ChannelEnum, params: T, id: number): void {
    let win = getWinById(id);
    win?.webContents?.send(key, params);
  }

  static removeListener<T extends FreeArray>(
    key: Ipc_ChannelEnum,
    fn: IpcMainListener<T>
  ): void {
    ipcMain.removeListener(key, fn);
  }

  static removeAllListeners(key: Ipc_ChannelEnum): void {
    ipcMain.removeAllListeners(key);
  }

  //移除 channel的所有handle
  static removeHandler(key: Ipc_ChannelEnum): void {
    ipcMain.removeHandler(key);
  }
}
